package lew.bing.gwalo.semaphoreLimiter;

import java.util.concurrent.Semaphore;

/**
 * Created by 刘国兵 on 2018/7/7.
 * 继承自java原生的信号量，但使用一个可改变的信号量做处理
 */
public class BingoSemaphore extends Semaphore {

    private volatile int permits;

    public BingoSemaphore(int permits) {
        super(permits);
        this.permits = permits;
    }

    public BingoSemaphore(int permits, boolean fair) {
        super(permits, fair);
        this.permits = permits;
    }

    public synchronized void rebasePermit(int newPermit) {
        if (newPermit == permits) {
            return;
        }
        int re = newPermit - permits;
        if (re > 0) {
            release(re);
        } else {
            reducePermits(-re);
        }
        this.permits = newPermit;
    }

    public synchronized boolean rebaseAndTryAcquire(int newPermit) {
        rebasePermit(newPermit);
        if (permits == 0) {
            throw new IllegalArgumentException("信号量为0，该功能无法使用");
        }
        return tryAcquire();
    }

    public synchronized void rebaseAndAcquire(int newPermit) throws InterruptedException,IllegalArgumentException {
        rebasePermit(newPermit);
        // 如果newPermit为0，则抛异常
        if (permits == 0) {
            throw new IllegalArgumentException("信号量为0，该功能无法使用");
        }
        acquire();
    }

    public int getPermits() {
        return permits;
    }
}
